<?php


namespace app\shop\service\chat;


use app\enterprise\model\Message;
use app\enterprise\model\User;
use app\shop\model\chat\GroupUserModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\BaseService;
use app\shop\service\until\FileService;
use GatewayClient\Gateway;
use think\facade\Db;
use think\facade\Log;

class MessageService extends BaseService
{
    protected $fileType = ['file', 'image', 'video', 'voice', 'emoticon'];

    public static function getInstance()
    {
        // TODO: Implement getInstance() method.
    }

    public function __construct()
    {
    }

    /**
     * 聊天列表
     * @param $userInfo
     * @param $chatSign
     * @param string $type
     * @param string $keywords
     * @param int $page
     * @param int $limit
     * @return array
     * @throws \Exception
     */
    public function getMessageList($userInfo, $chatSign, $type = "", $keywords = "", $page = 1, $limit = 10)
    {
        try {
            $where = [];
            $where[] = ['chat_sign', '=', $chatSign];
            $where[] = ['type', 'not in', ['event', 'system', 'new_order']];

            if ($type && $type != "all") {
                $map['type'] = $type;
            }
            if ($keywords) {
                $where[] = ['content', 'like', '%' . $keywords . '%'];
            }
            // 消息已读
            MessageService::setIsRead($chatSign, $userInfo['user_id']);

            $list = MessageModel::field('msg_id,id,from_user,content,chat_sign,type,create_time,at,file_id,
            file_cate,file_size,file_name,extends,quote,trans_msg,call_status')
                ->where($where)
                ->page($page)
                ->limit($limit)
                ->order('msg_id', 'desc')
                ->select()
                ->toArray();
            if ($list) {
                $list = array_reverse($list);
            }
            foreach ($list as &$v) {
                $content = str_encipher($v['content'], false);
                $ext = '';
                if (in_array($v['type'], $this->fileType)) {
                    if ($v['type'] == 'file') {
                        $content = FileService::getFullUrlById($v['file_id']);
                    } else {
                        $content = getFileUrl($content);
                    }
                    $ext = getExtUrl($content);
                }
                $fromUser = UserModel::where('user_id', $v['from_user'])->field('user_id,realname,avatar')->find();
                // 处理撤回的消息
                if ($v['type'] == "event") {
                    if ($v['from_user'] == $userInfo['user_id']) {
                        $content = "你" . $content;
                    } else {
                        $content = $fromUser['realname'] . $content;
                    }
                }
                $v['content'] = $content;
                $v['extUrl'] = $ext;
                $v['from_user'] = $fromUser;
                $v['sendTime'] = strtotime($v['create_time']) * 1000;
                $v['status'] = "succeed";
                $v['quote'] = $v['quote'] ? json_decode($v['quote']) : '';
            }
            return $list;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage() . $exception->getLine());
        }
    }

    // 聊天记录
    public function getMessageRecord($msgId, $userInfo, $chatSign, $listRows, $isFirst, $directional, $upPage, $downPage, $search, $isRead = 1, $type = 'all')
    {
        $where = [];
        $where[] = ['chat_sign', '=', $chatSign];
        if ($isRead) {
            $where[] = ['is_read', '=', 1];
        }
        if ($type && $type != 'all') {
            $where[] = ['type', '=', $type];
        }
        if ($search) {
            $where[] = ['content', 'like', '%' . $search . '%'];
        }
        // 从聊天框跳转到聊天记录没有传msg_id 此时获取最新的消息ID
        $maxId = MessageModel::where($where)->max('msg_id');

        $sort = 'msg_id desc';

        if ($directional == 0) {
            // 加载上边的内容
            $page = $upPage;
            if (!$msgId) {
                // 聊天记录查询
                $where[] = ['msg_id', '<=', $maxId];
            } else {
                // 从聊天记录搜索到消息 跳转回聊天记录 因为第一次多加载了几条数据 所以向上加载的时候要少查几条
                $msgId = $msgId ? $msgId : $maxId;
                $where1 = $where;
                $where1[] = ['msg_id', '<', $msgId];
                $beforeArr = Db::name('message')->where($where1)->order('msg_id', 'desc')->limit(3)->column('msg_id');
                $end = end($beforeArr);
                $msgId = $end ? $end : $msgId;
                $where[] = ['msg_id', '<', $msgId];
            }
        } else {

            $page = $downPage;
            // 从聊天记录搜索到消息 跳转回聊天记录 多加载了之前的几条数据
            $where1 = $where;
            $where1[] = ['msg_id', '<', $msgId];
            $beforeArr = Db::name('message')->where($where1)->order('msg_id', 'desc')->limit(3)->column('msg_id');
            $end = end($beforeArr);
            $msgId = $end ? $end : $msgId;
            // 加载下边的内容
            if ($isFirst == 1) {
                $where[] = ['msg_id', '>=', $msgId];
            } else {
                $where[] = ['msg_id', '>', $msgId];
            }
            $sort = 'msg_id asc';
        }
        $list = Message::getRecord($where, $sort, $listRows, $page);
        foreach ($list['data'] as $k => &$v) {
            $content = str_encipher($v['content'], false);
            $ext = '';
            if (in_array($v['type'], $this->fileType)) {
                if ($v['type'] == 'file') {
                    $content = FileService::getFullUrlById($v['file_id']);
                } else {
                    $content = getFileUrl($content);
                }
                $ext = getExtUrl($content);
            }
            $fromUser = UserModel::withTrashed()->where('user_id', $v['from_user'])->field('user_id,realname,avatar')->find();
            // 处理撤回的消息
            if ($v['type'] == "event") {
                if ($v['from_user'] == $userInfo['user_id']) {
                    $content = "你" . $content;
                } else {
                    $content = $fromUser['realname'] . $content;
                }
            }
            $v['content'] = $content;
            $v['extUrl'] = $ext;
            $v['from_user'] = $fromUser;
            $v['sendTime'] = strtotime($v['create_time']) * 1000;
            $v['status'] = "succeed";
            $v['quote'] = $v['quote'] ? json_decode($v['quote']) : '';
        }
        return $list;
    }


    /**
     * 获取其它用户聊天记录
     * @param $limit
     * @param $page
     * @param $search
     * @param $orderId
     * @param $type
     * @return array
     * @throws \Exception
     */
    public static function getOtherMessageRecord($orderId, $type, $search, $page, $limit)
    {
        try {
            $where = [];
            $where[] = ['status', '=', 1];
            $where[] = ['is_group', '=', 0];
            $where[] = ['order_id', '=', $orderId];
            $where[] = ['type', 'not in', ['event', 'system', 'new_order']];
            if ($type) {
                $where[] = ['type', '=', $type];
            }
            if ($search) {
                $where[] = ['content', 'like', '%' . $search . '%'];
            }
            $list = $list = Db::name('message')
                ->where($where)
                ->order('msg_id', 'desc')
                ->paginate(['list_rows' => $limit, 'page' => $page])
                ->toArray();
            $userList = User::matchUser($list['data'], true, 'from_user', 120);
            foreach ($list['data'] as $k => &$v) {
                $content = str_encipher($v['content'], false);
                $preview = '';
                $ext = '';
                if (in_array($v['type'], self::$fileType)) {
                    $content = getFileUrl($content);
                    $preview = previewUrl($content);
                    $ext = getExtUrl($content);
                }
                if (empty($userList[$v['from_user']])) {
                    continue;//用户信息为空时，不展示消息
                }
                $fromUser = $userList[$v['from_user']];
                // 处理撤回的消息
                $v['status'] = 'succeed';
                $v['sendTime'] = $v['create_time'] * 1000;
                $v['content'] = $content;
                $v['preview'] = $preview;
                $v['download'] = $v['file_id'] ? request()->domain() . '/filedown/' . encryptIds($v['file_id']) : '';
                $v['toContactId'] = $v['to_user'];
                $v['from_user'] = $fromUser;
                $v['extUrl'] = $ext;
                $v['extends'] = is_string($v['extends']) ? json_decode($v['extends'], true) : $v['extends'];
                $v['quote'] = $v['quote'] ? json_decode($v['quote']) : '';
                $v['toUserInfo'] = UserModel::field('user_id,realname,avatar')->where('user_id', $v['to_user'])->find();
            }
            return $list;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    // 设置消息已读
    public static function setIsRead($chatSign, $userId)
    {
        GroupUserModel::update(['unread' => 0], [['chat_sign', '=', $chatSign], ['user_id', '=', $userId]]);
    }

    public static function sendVoiceMsg($event, $code, $id, $fromUserId, $chatSign, $status, $sdp, $iceCandidate)
    {
        try {
            if ($event == 'calling') {
                $status = 3;
            }

            $callTime = time();
            if ($code == 906) {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $startTime = $message['call_start_time'];
                $diffTime = time() - $startTime;
                $minutes = floor($diffTime / 60);
                $seconds = $diffTime % 60;
                $callTime = sprintf('%d:%d', $minutes, $seconds);
            }
            switch ($code) {
                case 902:
                    $content = '已取消通话';
                    break;
                case 903:
                    $content = '已拒绝';
                    break;
                case 905:
                    $content = '未接通';
                    break;
                case 906:
                    $content = '通话时长 ' . $callTime;
                    break;
                case 907:
                    $content = '忙线中';
                    break;
                case 908:
                    $content = '其他端已操作';
                    break;
                default:
                    $content = '语音通话';
                    break;
            }
            switch ($event) {
                case 'calling':
                    $content = '语音通话';
                    break;
                case 'acceptRtc':
                    $content = '接听通话请求';
                    break;
                case 'iceCandidate':
                    $content = '数据交换中';
                    break;
                case 'busy':
                    $content = '忙线中';
                    break;
            }
            $fromUserInfo = UserModel::field('user_id,mobile,realname,avatar')->where('user_id', $fromUserId)->find();
            $toUserList = GroupUserModel::where('chat_sign', $chatSign)->with('user')->select();
            $data = [
                'id' => $id,
                'sendTime' => time() * 1000,
                'content' => $content,
                'type' => 'webrtc',
                'status' => 'succeed',
                'fromUser' => $fromUserInfo,
                'toUser' => $toUserList,
                'chat_sign' => $chatSign,
                'extends' => [
                    'type' => 0,    //通话类型，1视频，0语音。
                    'status' => $status, //，1拨打方，2接听方
                    'event' => $event,
                    'callTime' => $callTime,
                    'sdp' => $sdp,
                    'code' => $code,  //通话状态:呼叫901，取消902，拒绝903，接听904，未接通905，接通后挂断906，忙线907,其他端操作908
                    'iceCandidate' => $iceCandidate,
                    'isMobile' => 1,
                ]
            ];
            if ($event == 'calling') {
                $msg = [
                    'from_user' => $fromUserInfo['user_id'],
                    'from_user_role_id' => $fromUserInfo['role_id'],
                    'id' => $id,
                    'content' => str_encipher($content),
                    'chat_sign' => $chatSign,
                    'create_time' => time(),
                    'type' => $data['type'],
                    'is_group' => 0,
                    'is_read' => 0,
                    'extends' => $data['extends'],
                    'call_start_time' => time(),
                ];
                $message = new Message();
                $message->update(['is_last' => 0], ['chat_sign' => $chatSign]);
                $message->save($msg);
                $msg_id = $message->msg_id;
                $data['msg_id'] = $msg_id;
            } elseif ($event == 'hangup') {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $message->content = str_encipher($content);
                $extends = $message->extends;
                $extends['code'] = $code;
                $message->extends = $extends;
                $message->call_status = 0;
                $message->call_end_time = time();
                $message->save();
                $data['call_status'] = 0;
                $data['call_end_time'] = time();
                $data['msg_id'] = $message->msg_id;
            } elseif ($event == 'acceptRtc') {
                $message = Message::where(['id' => $id])->find();
                if (!$message) {
                    throw new \Exception('通话失败！');
                }
                $message->call_status = 2;
                $message->save();
                $data['call_status'] = 2;
                $data['msg_id'] = $message->msg_id;
            }
            $data['quote'] = new \stdClass();
            wsSendMsg($chatSign, 'webrtc', $data, 1);
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }
}